from django.shortcuts import render

# Create your views here.

from rest_framework.response import Response
from rest_framework.views import APIView

from oauth.models import OAuthQQUser
from oauth.serializers import OAuthQQUserSerializer
from oauth.utils import generic_openid_token


"""
实现第三方登陆的步骤：
①先到相应的开发平台中，申请成为开发者
        个人开发者
        企业开发者
②成为开发者之后，申请应用
③按照文档开发

    1、添加图标
    2、添加图标的点击按钮
    3、点击图标的时候 跳转到一个页面
    4、这个页面需要用户同意，同意之后获取一个code
    5、通过code换取token
    6、通过token 换取openid
        openid是次网站上唯一对用户身份的标识，
        网站可将次id进行存储 便于用户下次登陆时辨识器身份。
        或将其与用户在网站上的原有账号进行绑定。
        openid 和 已有账号进行一个1:1的绑定关系


对于应用而言，需要两步：
    1、获取Authorization Code;
    2、通过Authorization Code获取Access Token

"""
"""
后端需要拼接 跳转的url，拼接成功之后返回给前端



"""

from QQLoginTool.QQtool import OAuthQQ
from meiduo_mall import settings


class OauthQQurlAPIView(APIView):

    def get(self,request):

        state = 'test'
        #如果我们是在 订单页面登陆的化，需要在登陆成功之后，在跳转回订单页面
        state = '/'

        qq = OAuthQQ(client_id=settings.QQ_CLIENT_ID,client_secret=settings.QQ)

        auth_url = qq.get_qq_url()

        return Response({'auth_url':auth_url})





"""
步骤：
    ①当用户同意登陆之后，腾讯的服务器会生成一个code，这个code在回溯的url中
    我们需要让前端将code传递给后端

    ②后端需要通过code 换取 token

    ③通过token 换取 openid
确定请求方式和路由：
    GET /oauth/qq/users/?code=xxx
确定那个视图

"""
class OAuthQQUserAPIView(APIView):

    def get(self,request):
        #1、接受code
        code = request.query_params.get('code')
        if code is None:
            from rest_framework import status

            return Response(status=status.HTTP_400_BAD_REQUEST)

        #2、通过code换取token（我们通过 请求 向腾讯的服务器换）
        qq = OAuthQQ(client_id=settings.QQ_CLIENT_ID,client_secret=settings.QQ_CLIENT_SECRET,redirect_uri=settings.QQ_REDIRECT_URI)
        token = qq.get_access_token(code)

        #3、通过token换取openid
        openid = qq.get_open_id(token)

        #4、我们需要根据openid进行判断
        #   如果用户绑定过，则直接登陆
        #   如果用户没有绑定过，则进行绑定
        try:
            qquser = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            #说明不存在，就应该绑定
            #1、openid属于敏感数据
            #2、绑定的时候应该有一个时效

            #对openid进行一个加密（签名的处理）
            openid_token = generic_openid_token(openid)

            return Response({'access_token':openid_token})
        else:
            #说明存在，就应该登陆
            from rest_framework_jwt.settings import api_settings

            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            payload = jwt_payload_handler(qquser.user)
            token = jwt_encode_handler(payload)

            return Response({
                'user_id':qquser.user.id,
                'username':qquser.user.username,
                'token':token
            })


    def post(self,request):
        #1、接受参数 mobile,password,sms_code,access_token
        data = request.data

        #2、验证数据
        #   根据手机号判断用户是否注册过
        serializer = OAuthQQUserSerializer(data=data)
        serializer.is_valid(raise_exception=True)

        #3、保存数据
        qquser = serializer.save()

        #4、返回响应
        from rest_framework_jwt.settings import api_settings

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(qquser.user)
        token = jwt_encode_handler(payload)

        return Response({
            'user_id': qquser.user.id,
            'username': qquser.user.username,
            'token': token
        })


"""
当用户点击头像授权同意的时候，后端会将 生成的code换取成最终的openid，然后返回给前端

当用户点击保存的时候，需要让前端将 手机号，密码，短信验证码以及 加密之后的openid提交给后端

后端思路：
    1、接受参数 mobile,password,sms_code,access_token
    2、验证数据  access_token  sms_code
        根据手机号判断用户是否注册过
    3、保存数据
    4、返回响应

"""




############################ JWS #########################################3
#1、导入
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from meiduo_mall import settings

#2、初始化，创建序列化器实例对象
#secret_key 秘钥   一般使用setting中的secret_key
# expires_in  过期时间
serializer = Serializer(secret_key=settings.SECRET_KEY,expires_in=60*60)

#3、组织数据
data = {
    'openid':'123'
}

#4、对数据进行加密(签名)
token = serializer.dumps(data)
token.decode()

##########################验证数据#############################3

#1、创建序列化器
serializer = Serializer(secret_key=settings.SECRET_KEY,expires_in=60*60)

#2、对数据进行解密
serializer.loads(token)


############################验证数据的合法性############################################3

serializer = Serializer(secret_key=settings.SECRET_KEY,expires_in=1000)

data = {'openid':'123'}

token = serializer.dumps(data)

serializer.loads(token)




















